home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / zmdm_src / transfer.c < prev    next >
C/C++ Source or Header  |  1988-06-26  |  16KB  |  968 lines

  1. /*
  2.  *     (Quick & Dirty) Transfer Shell
  3.  *
  4.  *        Jwahar Bammi
  5.  *            usenet: mandrill!bammi@{decvax,sun}.UUCP
  6.  *            csnet:  bammi@mandrill.ces.CWRU.edu
  7.  *            arpa:   bammi@mandrill.ces.CWRU.edu
  8.  *            CompuServe: 71515,155
  9.  */
  10.  
  11. #include "config.h"
  12.  
  13. #ifdef DLIBS
  14. #include <string.h>
  15. #endif
  16.  
  17. #include "zmdm.h"
  18. #include "common.h"
  19.  
  20. #define ISWILD(X)    ((X == '*')||(X == '?'))
  21. #define PROMPT        fprintf(STDERR,"zmdm> ")
  22.  
  23. extern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(),
  24.        hhelp();
  25.  
  26. #ifdef RECURSE
  27. extern int doszf();
  28. #endif
  29.  
  30. static struct comnds {
  31.     char    *command;    /* command string    */
  32.     int     (*routine)();    /* routine to invoke    */
  33.     char    *synopsis;    /* synopsis        */
  34.     int    expand;        /* expand wildcards before calling routine? */
  35. } comtab [] = {
  36.     { "rz",    dorz, "receive files using Z/X modem protocol",       TRUE },
  37.     { "rb", dorz, "receive files using Y modem protocol",         TRUE },
  38. #ifdef RECURSE
  39.     { "sz", doszf, "send files using Z/Y/X modem protocol",        TRUE },
  40. #else
  41.     { "sz", dosz, "send files using Z/Y/X modem protocol",        TRUE },
  42. #endif
  43.     { "sb", dosz, "send files using Y modem protocol",            TRUE },
  44.     { "rm", rm,   "remove files",                                 TRUE },
  45.     { "cp", cp,   "copy files",                                   TRUE },
  46.     { "ls", ls,   "list directory",                               FALSE},
  47.     { "cd", cd,   "change working directory",             FALSE},
  48.     { "md", md,   "make a directory",                 FALSE},
  49.     { "rd", rd,   "remove a directory",                     FALSE},
  50.     { "pwd",pwd,  "print  working directory",             FALSE},
  51.     { "df", df,   "check free space",                 FALSE},
  52.     { "?",  hhelp, "this message",                     FALSE},
  53.     { (char *)NULL, (int (*)())NULL, (char *)NULL,                   FALSE}
  54. };
  55.  
  56. #define MAXARGS    1024
  57. static char *targv[MAXARGS];
  58. static int targc;
  59. char *alltolower();
  60.  
  61. transfer()
  62. {
  63.     char linebuf[132];
  64.     char *line;
  65.     int command;
  66.     int status;
  67.     extern int find_command();
  68.     extern int expnd_args();
  69. #ifdef DEBUG
  70.     int i;
  71. #endif
  72.  
  73.     fprintf(STDERR,"hit <RETURN> to return to emulator,  <?> for help\n\n");
  74.     targc = 0;
  75.     while (TRUE)
  76.     {
  77.         if(targc > 1)
  78.             free_args();
  79.  
  80.         PROMPT;
  81.         linebuf[0] = 127;
  82. #ifndef REMOTE
  83.         Cconrs(linebuf);
  84. #else
  85.         Cconraux(linebuf);
  86. #endif
  87.         putc('\n', STDERR);
  88.         if(linebuf[1] == 0)
  89.         /* cancelled */
  90.         return;
  91.         
  92.         linebuf[(linebuf[1]+2)] = '\0';
  93.         line = &linebuf[2];
  94. #ifdef DEBUG
  95. printf("Line: |%s|\n", line);
  96. #endif
  97.  
  98.         targv[0] = line;
  99.         targc    = 1;
  100.     
  101.         /* pick up targv[0] */
  102.         while((*line != '\0') && (!isspace(*line)))
  103.             line++;
  104.  
  105.         if(*line != '\0')
  106.         {
  107.             *line++ = '\0';
  108.         }
  109.  
  110.         if((command = find_command(targv[0])) < 0)
  111.         {
  112.             fprintf(STDERR,"Invalid Command\n");
  113.             continue;
  114.         }
  115.  
  116.         if(expnd_args(line, comtab[command].expand))
  117.             /* too many args */
  118.             continue;
  119. #ifdef DEBUG
  120. printf("targc %d\n", targc);
  121. for(i = 0; i < targc; i++)
  122.     printf("%s ", targv[i]);
  123. printf("\n\n");
  124. #endif
  125.  
  126.         if((status = (*(comtab[command].routine))(targc, targv)) != 0)
  127.             fprintf(STDERR,"Exit Status %d\n", status);
  128.  
  129. #ifdef DEBUG
  130. printf("Exit Status %d\n", status);
  131. #endif
  132.  
  133.     } /* While */
  134. }
  135.  
  136. /*
  137.  * Straight sequential search thru comtab
  138.  */        
  139. int find_command(s)
  140. register char *s;
  141. {
  142.     register int i;
  143.  
  144.     for(i = 0; comtab[i].command != (char *)NULL; i++)
  145.     {
  146.         if(strcmp(s, comtab[i].command) == 0)
  147.             return i;
  148.     }
  149.  
  150.     return -1;
  151. }
  152.  
  153. /*
  154.  * Expand command line args, return TRUE if too many args, or Not matching Quotes
  155.  */
  156. int expnd_args(s, expand_wild)
  157. register char *s;
  158. int expand_wild;
  159. {
  160.     char next_arg[128];
  161.     register char *p;
  162.     register int contains_wild;
  163.     extern int add_argv();
  164.     extern int handl_wild();
  165.  
  166.     while(*s != '\0')
  167.     {
  168.         p = next_arg;
  169.         while(isspace(*s)) s++; /* skip leading space */
  170.         if(*s != '\0')
  171.         {
  172.             contains_wild = FALSE;
  173.             if(*s == '\047')
  174.             {
  175.                 /* Quoted arg */
  176.                 s++;
  177.                 while((*s != '\0') && (*s != '\047'))
  178.                     *p++ = *s++;
  179.                 *p = '\0';
  180.                 if(*s == '\0')
  181.                 {
  182.                     fprintf(STDERR,"No Matching Quote\n");
  183.                     return TRUE;
  184.                 }
  185.                 else
  186.                     s++;
  187.                 if(add_argv(next_arg))
  188.                     return TRUE;
  189.             }
  190.             else
  191.             {
  192.                 while(!isspace(*s) && (*s != '\0'))
  193.                 {
  194.                     contains_wild |= ISWILD(*s);
  195.                     *p++ = *s++;
  196.                 }
  197.                 *p = '\0';
  198.  
  199.                 if(contains_wild && expand_wild)
  200.                 {
  201.                     if(handl_wild(next_arg))
  202.                         return TRUE;
  203.                 }
  204.                 else
  205.                 {
  206.                     if(add_argv(next_arg))
  207.                         return TRUE;
  208.                 }
  209.             } /* if-else */
  210.         } /* If */
  211.     } /* while */
  212.  
  213.     return FALSE;
  214. }
  215.  
  216. /*
  217.  * add an arg to argv. Return TRUE if error
  218.  */
  219. int add_argv(s)
  220. char *s;
  221. {
  222.     extern char *myalloc();
  223.     extern char *strcpy();
  224.     extern int strlen();
  225.  
  226.     if(targc > (MAXARGS-1))
  227.     {
  228.         fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS);
  229.         return TRUE;
  230.     }
  231.     targv[targc++] = strcpy(myalloc(strlen(s)+1), s);
  232.     
  233.     return FALSE;
  234.     
  235. }
  236.  
  237. /*
  238.  * expand wild card arguments. Return TRUE on error.
  239.  */
  240. int handl_wild(s)
  241. char *s;
  242. {
  243.     extern struct stat statbuf;
  244.     extern char *mkpathname();
  245.     
  246.     if(Fsfirst(s, 0x21) != 0)
  247.     {
  248.         /* No match */
  249.         fprintf(STDERR,"No Match for %s\n", s);
  250.         return TRUE;
  251.     }
  252.  
  253.     alltolower(statbuf.st_name);
  254.     if(add_argv(mkpathname(s, statbuf.st_name)))
  255.         return TRUE;
  256.  
  257.     while(Fsnext() == 0)
  258.     {
  259.         alltolower(statbuf.st_name);
  260.         if(add_argv(mkpathname(s, statbuf.st_name)))
  261.             return TRUE;
  262.     }
  263.  
  264.     return FALSE;
  265. }
  266.  
  267. /*
  268.  * Given a spec with a trailing wildcard and a base will name construct pathname
  269.  *
  270.  */
  271. char *mkpathname(spec, file)
  272. register char *spec, *file;
  273. {
  274.     extern char *rindex();
  275.     register char *p;
  276.  
  277.     if((p = rindex(spec, '\\')) == (char *)NULL)
  278.         /* no path name */
  279.         return file;
  280.  
  281.     while(*file != '\0')
  282.         *++p = *file++;
  283.     *++p = '\0';
  284.     
  285.     return spec;
  286. }
  287.  
  288. free_args()
  289. {
  290.     register int i;
  291.     
  292.     for(i = 1; i < targc; i++)
  293.         free(targv[i]);
  294. }
  295.  
  296. /*
  297.  * remove files
  298.  *    Usage: rm [-i] files ... 
  299.  */    
  300. int rm(argc, argv)
  301. register int argc;
  302. register char **argv;
  303. {
  304.     register int interactive;
  305.     register int status, s;
  306.     extern int yesno();
  307.     extern int errno;
  308.  
  309.     interactive = FALSE;
  310.     status = 0;
  311.     while(--argc)
  312.     {
  313.         ++argv;
  314.         if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') )
  315.             interactive = TRUE;
  316.         else
  317.         {
  318.             if(interactive)
  319.                 if(!yesno("rm: remove", *argv))
  320.                     continue;
  321.             if(unlink(*argv))
  322.             {
  323.                 s |= 1;
  324.                 fprintf(STDERR, "%s: no such file\n", *argv);
  325.             }
  326.             status |= s;
  327.         }
  328.     }
  329.     return status;
  330. }
  331.  
  332. /*
  333.  * Prompt and return Yes/No truth value
  334.  *
  335.  */
  336. int yesno(p1, p2)
  337. register char *p1, *p2;
  338. {
  339.     char reply[16];
  340.  
  341.     fprintf(STDERR,"%s %s (y/n): ", p1, p2);
  342.     reply[0] = 16;
  343. #ifndef REMOTE
  344.     Cconrs(reply);
  345. #else
  346.     Cconraux(reply);
  347. #endif
  348.  
  349.     putc('\n', STDERR);
  350.     return ( (reply[2] == 'y') || (reply[2] == 'Y') );
  351.  
  352. }
  353.  
  354. /*
  355.  * copy files
  356.  *    Usage:
  357.  *        cp src dest
  358.  *        or
  359.  *        cp files.. directory
  360.  */
  361. int cp(argc, argv)
  362. int argc;
  363. char **argv;
  364. {
  365.     char dest[128];
  366.     register int status;
  367.     extern int strlen();
  368.     extern int cpy();
  369.     extern char *basename();
  370.     
  371.     status = 0;
  372.     if(argc > 3)
  373.     {
  374.         register int i;
  375.  
  376.         if(!existd(argv[argc-1]))
  377.         {
  378.             fprintf(STDERR,"%s does not exists or is not a directory\n",
  379.                 argv[argc-1]);
  380.             return 1;
  381.         }
  382.  
  383.         for(i = 1; i < argc - 1; i++)
  384.         {
  385.             strcpy(dest, argv[argc-1]);
  386.             if( (argv[argc-1])[(strlen(argv[argc-1])-1)] != '\\')
  387.                 strcat(dest, "\\");
  388.             strcat(dest, basename(argv[i]));
  389.  
  390.             fprintf(STDERR,"copying %s to %s\n", argv[i], dest);
  391.             status |= cpy(argv[i], dest);
  392.         }
  393.     }
  394.     else
  395.     {
  396.         if(argc > 2)
  397.         {
  398.             if(existd(argv[2]))
  399.             {
  400.                 /* dest is a directory */
  401.                 strcpy(dest, argv[2]);
  402.                 if( (argv[2])[(strlen(argv[2])-1)] != '\\')
  403.                     strcat(dest, "\\");
  404.  
  405.                 strcat(dest, basename(argv[1]));
  406.  
  407.                 fprintf(STDERR,"copying %s to %s\n", argv[1], dest);
  408.                 return (cpy(argv[1], dest));
  409.             }
  410.  
  411.             if(strcmp(argv[1], argv[2]) == 0)
  412.             {
  413.                 fprintf(STDERR,"Cannot copy a file onto itself\n");
  414.                 return 3;
  415.             }
  416.             status = cpy(argv[1], argv[2]);
  417.         }
  418.         else
  419.         {
  420.             fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n");
  421.             return 2;
  422.         }
  423.     }
  424.  
  425.     return status;
  426. }
  427.  
  428.  
  429. /*
  430.  * Cpy src -> dest
  431.  *
  432.  */
  433. int cpy(src, dest)
  434. char *src, *dest;
  435. {
  436.     register int fps,fpd;
  437.     register long count;
  438.     register int status;
  439.  
  440.     status = 0;
  441.  
  442.     if((fps = Fopen(src, 0)) < (-3))
  443.     {
  444.         status = fps;
  445.         fprintf(STDERR,"%s: no such file\n", src);
  446.         return status;
  447.     }
  448.  
  449.     if((fpd = Fcreate(dest, 0)) < (-3))
  450.     {
  451.         if((fpd = Fopen(dest, 1)) < (-3))
  452.         {
  453.             Fclose(fps);
  454.             status = fpd;
  455.             fprintf(STDERR,"%s: cannot create\n",dest);
  456.             return status;
  457.         }
  458.     }
  459.     
  460.     while( (count = Fread(fps, (long)BBUFSIZ, bufr)) > 0L)
  461.     {
  462.         if(Fwrite(fpd, count, bufr) != count)
  463.         {
  464.             status = 1;
  465.             fprintf(STDERR,"Error Writing %s\n",dest);
  466.             break;
  467.         }
  468.     }
  469.     if(count < 0L)
  470.     {
  471.         status = 2;
  472.         fprintf(STDERR,"Error Reading %s\n", src);
  473.     }
  474.  
  475.     Fclose(fpd);
  476.     Fclose(fps);
  477.  
  478.     return status;
  479. }
  480.  
  481. #define haswild(X) \
  482. ( (rindex(X,'*') != (char *)NULL) || (rindex(X,'?') != (char *)NULL) )
  483.  
  484. /*
  485.  * list directories
  486.  */
  487. int ls(argc, argv)
  488. int argc;
  489. char **argv;
  490. {
  491.     char path[128];
  492.     register char *p;
  493.     extern char *rindex();
  494.     extern int existd();
  495.  
  496.     if(argc < 2)
  497.         lis("*.*");
  498.     else
  499.     {
  500.         while(--argc)
  501.         {
  502.             ++argv;
  503.             if((p = rindex(*argv,'\\')) == (char *)NULL)
  504.                 p = *argv;
  505.             else
  506.                 p++;
  507.             if(*p == '\0')
  508.             {
  509.                 strcpy(path, *argv);
  510.                 strcat(path,"*.*");
  511.             }
  512.             else
  513.             {
  514.                 if(haswild(p))
  515.                     strcpy(path, *argv);
  516.                 else
  517.                 {
  518.                     if(existd(p))
  519.                     {
  520.                         strcpy(path, *argv);
  521.                         strcat(path, "\\*.*");
  522.                     }
  523.                     else
  524.                         strcpy(path, *argv);
  525.                 }
  526.             }
  527.             lis(path);
  528.         } /* while */
  529.     }
  530.     
  531.     return 0;
  532. }
  533.  
  534. /*
  535.  * given a possibly wild carded string put out list of subtrees
  536.  *
  537.  */
  538. lis(wild)
  539. char *wild;
  540. {
  541.     extern struct stat statbuf;
  542.     register int count;
  543.  
  544. #ifdef DEBUG
  545. printf("ls %s\n", wild);
  546. #endif
  547.  
  548.     if(Fsfirst(wild, 0x0020 | 0x0010) != 0)
  549.     {
  550.         fprintf(STDERR,"%s - no match.\n", wild);
  551.         return;
  552.     }
  553.  
  554.     count = 0;
  555.     alltolower(statbuf.st_name);
  556.     if(!((strcmp(statbuf.st_name,".") == 0) || 
  557.        (strcmp(statbuf.st_name, "..") == 0)))
  558.         putls(&statbuf, ++count);
  559.  
  560.     while(Fsnext() == 0)
  561.     {
  562.         alltolower(statbuf.st_name);
  563.         if(!((strcmp(statbuf.st_name,".") == 0) || 
  564.            (strcmp(statbuf.st_name, "..") == 0)))
  565.             putls(&statbuf, ++count);
  566.     }
  567.  
  568.     if((count % 4))
  569.         putc('\n', STDERR);
  570.  
  571. }
  572.  
  573. /*
  574.  * Put out a directory entry
  575.  */
  576. putls(statbuf, count)
  577. register struct stat *statbuf;
  578. register int count;
  579. {
  580.     char dbuf[16];
  581.  
  582.     if((statbuf->st_mode) & 0x0010)
  583.     {
  584.         /* subtree */
  585.         strcpy(dbuf, statbuf->st_name);
  586.         strcat(dbuf, "/");
  587.         fprintf(STDERR,"%-13s      ", dbuf);
  588.     }
  589.     else
  590.         /* file */
  591.         fprintf(STDERR,"%-12s %5ld ", statbuf->st_name, statbuf->st_size);
  592.     
  593.     if(!(count %4))
  594.         putc('\n', STDERR);
  595. }
  596.  
  597. /*
  598.  * Change working directory
  599.  */
  600. int cd(argc, argv)
  601. int argc;
  602. char **argv;
  603. {
  604.     register char *d, *path;
  605.     register int drive;
  606.     extern char *index();
  607.  
  608.     if((argc < 2) || (argc > 2))
  609.     {
  610.         fprintf(STDERR,"Usage: cd directory\n");
  611.         return 1;
  612.     }
  613.  
  614.  
  615.     
  616.     if((d = index(argv[1],':')) == (char *)NULL)
  617.     {
  618.         /* Drive was not specified, must mean the current drive */
  619.         path = argv[1];
  620.     }
  621.     else
  622.     {
  623.         d--;
  624.         if(isupper(*d))
  625.         {
  626.             *d = tolower(*d);
  627.         }
  628.         drive = *d - 'a';
  629.         if(d[2] != '\\')    /* just gave D: */
  630.         {
  631.             /* we will shove in the '\' */
  632.             d[1] = '\\';
  633.             path = &d[1];
  634.         }
  635.         else
  636.             path = &d[2];
  637.  
  638.         /* Set the Drive */
  639.         if(Dsetdrv(drive) < 0)
  640.         {
  641.             fprintf(STDERR,"Could not set drive %c:\n", *d);
  642.             return 2;
  643.         }
  644.  
  645.     }
  646.  
  647.  
  648.     /* Set the Path */
  649.     if(Dsetpath(path) != 0)
  650.     {
  651.         fprintf(STDERR,"Could not set directory %s\n", path);
  652.         return 3;
  653.     }
  654.     
  655.     return 0;
  656.     
  657. }
  658.  
  659. /*
  660.  * pwd - figure out the current working directory
  661.  *
  662.  */
  663. int pwd()
  664. {
  665.     register int drive;
  666.     char _cwd[128];
  667.     
  668.     drive = Dgetdrv();
  669.     Dgetpath(&_cwd[3],0);
  670.     fprintf(STDERR,"%c:%s%s\n", (drive + 'a'),
  671.         ((_cwd[3] == '\\')? "" : "\\"), &_cwd[3]);
  672.  
  673.     return 0;
  674. }
  675.  
  676. /*
  677.  * Print free space
  678.  */
  679. int df(argc, argv)
  680. int argc;
  681. char **argv;
  682. {
  683.     struct {
  684.         long b_free;
  685.         long b_total;
  686.         long b_secsiz;
  687.         long b_clsiz;
  688.     } fbuf;
  689.  
  690.     register int drive;
  691.     register long ffree, total;
  692.     extern long drv_map;
  693.  
  694.     if(argc > 1)
  695.     {
  696.         ++argv;
  697.         drive = (*argv)[0];
  698.         if(isupper(drive))
  699.             drive = tolower(drive);
  700.  
  701.         drive = drive - 'a';
  702.         if((drv_map & (1L << drive)) == 0)
  703.         {
  704.             fprintf(STDERR,"Invalid Drive %c:\n", (drive + 'a'));
  705.             return 1;
  706.         }
  707.         drive +=1;
  708.     }
  709.     else
  710.         drive = Dgetdrv()+1;    /* default current drive */
  711.  
  712.     fprintf(STDERR,"Please Wait .....");
  713.     Dfree(&fbuf,drive);
  714.     ffree = fbuf.b_free * fbuf.b_clsiz * fbuf.b_secsiz;
  715.     total =    fbuf.b_total * fbuf.b_clsiz * fbuf.b_secsiz;
  716.     fprintf(STDERR,"\r%ld Bytes (", ffree);
  717.     prratio(STDERR, ffree, total);
  718.     fprintf(STDERR, ") Free on drive %c:\n", ((drive-1) + 'a'));
  719.  
  720.     return 0;
  721. }
  722.  
  723.  
  724. /*
  725.  * print a ratio
  726.  * avoid floats like the plague
  727.  */
  728. prratio(stream, num, den)
  729. FILE *stream;
  730. long  num, den;
  731. {
  732.         register int q;                 /* Doesn't need to be long */
  733.  
  734.         if(num > 214748L) {             /* 2147483647/10000 */
  735.                 q = num / (den / 10000L);
  736.         } else {
  737.                 q = 10000L * num / den;         /* Long calculations, though */
  738.         }
  739.         if (q < 0) {
  740.                 putc('-', stream);
  741.                 q = -q;
  742.         }
  743.         fprintf(stream, "%d.%02d%%", q / 100, q % 100);
  744. }
  745.  
  746. /*
  747.  * Make directories
  748.  */
  749. int md(argc, argv)
  750. int argc;
  751. char **argv;
  752. {
  753.     register int status, s;
  754.  
  755.     status = 0;
  756.     while(--argc)
  757.     {
  758.         ++argv;
  759.         if(( s = Dcreate(*argv)))
  760.         {
  761.             status |= s;
  762.             fprintf(STDERR,"Could not create %s\n", *argv);
  763.         }
  764.     }
  765.  
  766.     return status;
  767. }
  768.  
  769. /*
  770.  * Remove directories
  771.  */
  772. int rd(argc, argv)
  773. int argc;
  774. char **argv;
  775. {
  776.     register int status, s;
  777.  
  778.     status = 0;
  779.     while(--argc)
  780.     {
  781.         ++argv;
  782.         if(( s = Ddelete(*argv)))
  783.         {
  784.             status |= s;
  785.             fprintf(STDERR,"Could not delete %s\n", *argv);
  786.         }
  787.     }
  788.  
  789.     return status;
  790. }
  791.  
  792.  
  793. /*
  794.  * Allocate memory with error check
  795.  *
  796.  */
  797. char *myalloc(size)
  798. unsigned int size;
  799. {
  800.     register char *m;
  801.     extern char *malloc();
  802.  
  803.     if((m = malloc(size)) == (char *)NULL)
  804.     {
  805.         fprintf(STDERR,"Out of Memory\nSorry, cannot continue\n");
  806.         exit(1);
  807.     }
  808.  
  809.     return m;
  810. }
  811.  
  812. /*
  813.  * Put out help
  814.  */
  815. int hhelp()
  816. {
  817.     register int i;
  818.  
  819. #ifdef REMOTE
  820.     fprintf(STDERR,"\n\t\t\t    Available Commands \n\n");
  821. #else
  822.     fprintf(STDERR,"\n\t\t\t   \033p Available Commands \033q\n\n");
  823. #endif
  824.     for(i = 0; comtab[i].command != (char *)NULL; i++)
  825.     {
  826.         fprintf(STDERR,"\t%s\t%s\n", comtab[i].command,
  827.             comtab[i].synopsis);
  828.     }
  829.     fprintf(STDERR,"\n\tor hit <RETURN> to exit to terminal emulator\n\n");
  830.     return 0;
  831.  
  832. }
  833.  
  834. /*
  835.  * Lower case string
  836.  */
  837. char *alltolower(s)
  838. register char *s;
  839. {
  840.     register char *p;
  841.  
  842.     for(p = s; *p != '\0'; p++)
  843.     {
  844.         if(isupper(*p))
  845.             *p = tolower(*p);
  846.     }
  847.     return s;
  848. }
  849.  
  850. /*
  851.  * return the base filename, given (potentially) a pathname
  852.  */
  853. char *basename(s)
  854. register char *s;
  855. {
  856.     register char *p;
  857.     extern char *rindex();
  858.  
  859.     if((p = rindex(s, '\\')) == (char *)NULL)
  860.     {
  861.         if((p = rindex(s, ':')) == (char *)NULL)
  862.             return s;
  863.         else
  864.             return ++p;
  865.     }
  866.     return ++p;
  867. }
  868.  
  869. #ifdef RECURSE
  870. int doszf(argc, argv)
  871. int argc;
  872. char **argv;
  873. {
  874.     extern int expandargs();
  875. #ifdef DDEBUG
  876. int i;
  877. printf("doszf: argc %d\n", argc);
  878. for(i = 0; i < argc; i++)
  879.     printf("%s ", argv[i]);
  880. printf("\n\n");
  881. #endif
  882.  
  883.     return(expandargs(dosz, argc, argv));
  884. }
  885.  
  886. #include "expandar.c"
  887.  
  888. #endif
  889.  
  890. #ifdef REMOTE
  891. /*
  892.  * Read a line from the Aux port
  893.  *
  894.  */
  895.  
  896. Cconraux(l)
  897. char *l;
  898. {
  899.     register int c;
  900.     register int count;
  901.     register char *p;
  902.  
  903.     p = &l[2];
  904.     count = 0;
  905.  
  906.     while((c = get_a_c()) != '\n')
  907.     {
  908.         *p++ = c;
  909.         count++;
  910.     }
  911.     l[1] = count;
  912. }
  913.  
  914. static char _chr_buf[128];
  915. static int _n_chr = 0;
  916. static char *_next_chr = &_chr_buf[0];
  917. static char *_next_avail = &_chr_buf[0];
  918.  
  919. int get_a_c()
  920. {
  921.         register int c;
  922.  
  923.         if(_n_chr > 0)
  924.         {
  925.                 _n_chr--;
  926.                 return(*_next_avail++);
  927.         }
  928.         
  929.         _n_chr = 0;
  930.         _next_avail = &_chr_buf[0];
  931.         _next_chr = &_chr_buf[0];
  932.  
  933.         while( ((c = Bconin(1) & 0x7fff) != '\r') && (c != '\n'))
  934.         {
  935.                 if((c == '\003') || (c == '\025'))
  936.                 {
  937.             while(_n_chr-- > 0)
  938.                 wr_modem("\b \b");
  939.                         _n_chr = 0;
  940.                         _next_avail = &_chr_buf[0];
  941.                         _next_chr = &_chr_buf[0];
  942.  
  943.                 }
  944.  
  945.                 if((c == '\b') || (c == '\177'))
  946.                 {
  947.                         if(_n_chr > 0)
  948.                         {
  949.                                 _next_chr--;
  950.                                 _n_chr--;
  951.                                 wr_modem("\b \b");
  952.                         }
  953.                 }
  954.                 else
  955.                 {
  956.                         *_next_chr++ = c;
  957.                         _n_chr++;
  958.             Bconout(1, c);
  959.                 }
  960.         }
  961.  
  962.         *_next_chr = '\n';
  963.         return(*_next_avail++);
  964. }
  965. #endif /* REMOTE */
  966.  
  967. /* -eof- */
  968.